/*
 * customer.h
 *
 *  Created on: Apr 22, 2011
 *      Author: mistadj
 */

#ifndef CUSTOMER_H_
#define CUSTOMER_H_

#include "list.h"
#include "car.h"

typedef struct Customer_t *Customer;

typedef enum {
	CUSTOMER_NULL_ARGUMENT,
	CUSTOMER_OUT_OF_MEMORY,
	CUSTOMER_CAR_NOT_RENTED,
	CUSTOMER_SUCCESS
} CustomerResult;

/**
 * this file was made in order to define a new type (the customer type)
 * which can later be stored in a set or a list. two types of functions
 * are defined in this file. the first is functions that are made to
 * handle one element of type customer, and the other is the type that is
 * made for sorting a list or storing the type in a set (copy, free,
 * compare, filter).
 *
 * Note: many of the functions do not handle the case when receiving a NULL
 * pointer. when the handling of a NULL pointer is not defined in the
 * description of function, you should check for such NULLs before sending
 * them pointers to the function.
 */

/**
 * the function to sent when creating a list or a set to
 * unable copying a customer
 * @param customer - the customer to copy
 * return
 * NULL if element is NULL or memory allocation failed
 * 	a void pointer to the new created element
 */
void* copyCustomer(void* element);

/**
 * the function to sent when creating a list or set to
 * unable deleting a customer
 * @param customer - the customer to free
 */
void freeCustomer(void* element);

/**
 * the comparing function to be used by a set or a list
 * to compare two customers IDs
 *@param customer1 - the first customer
 *@param customer2 - the second customer
 * return:
 * 	a positive number if the ID of customer1 is greater
 * 	0 if its the same ID
 * 	a negative number otherwise
 */
int compareCustomerId(void* element1, void* element2);

/**
 * the comparing function to be used by a set or a list
 * to compare two customers fee.
 *@param customer1 - the first customer
 *@param customer2 - the second customer
 * return:
 * 	a negative number if the fee of customer1 is greater
 * 	0 if the fee is equal
 * 	a positive number otherwise
 */
int compareCustomerFee(void* element1, void* element2);

/**
 * this fucntion will return true if customer has a fee (greater than 0)
 * @param customer - the customer to check its fee
 * return:
 * 	true if fee>0 , false otherwise.
 */
bool customerFilterOutNoFee(void* element);

/**
 * customerCreate: creates a new customer
 * @param id - the customer's ID
 * @param name - the customer's name
 * return
 *  the created customer,
 *  or NULL if memory allocation failed or if name is NULL.
 */
Customer customerCreate(int id, char* name);

/**
 * customerRentCar: adds a car to the list of cars rented by the customer
 * @param customer - the customer to add the car to
 * @param car - the car to add
 * return
 *	CUSTOMER_NULL_ARGUMENT - if customer or car is NULL
 *	CUSTOMER_OUT_OF_MEMORY - if failed creating a copy of the car
 *	CUSTOMER_SUCCESS - if everything was OK
 */
CustomerResult customerRentCar(Customer customer, Car car);

/**
 * customerReturnCar: returns a car that was rented by the customer.
 * the function includes the update of the bill for the customer.
 * @param customer - the customer who's returning the car
 * @param license - the license number of the car
 * @param km - the distance traveled by the car since it was rented
 * return
 *  CUSTOMER_NULL_ARGUMENT - if customer is NULL
 *  CUSTOMER_CAR_NOT_RENTED - if the car wasn't rented by the customer
 *	CUSTOMER_OUT_OF_MEMORY - if memory allocation failed.
 *  CUSTOMER_SUCCESS - if everything was OK
 */
CustomerResult customerReturnCar(Customer customer, int license, int km);

/**
 * customerGetName: gets the name of the customer
 * @param customer - the customer who's name's we're interested in
 * return
 * 	NULL if customer is NULL
 * 	the customer's name otherwise
 */
char* customerGetName(Customer customer);

/**
 * customerGetId: gets the ID of the customer
 * @param customer - the customer who's ID's we're interested in
 * return
 * 	the customer's ID
 */
int customerGetId(Customer customer);

/**
 * customerGetFee: gets the current fee of the customer
 * @param customer - the customer who's fee we're interested in
 * return
 * 	the customer's fees
 */
int customerGetFee(Customer customer);

/**
 * @param customer - the customer to check
 * return
 * 	the sum of past payments of this customer
 */
int customerGetPastPayment(Customer customer);
/**
 * get a list of bills for a customer
 * @param customer - the customer to check
 * return:
 * 	NULL if customer is NULL or memory allocation failed.
 * 	a list of the customer's bills otherwise (of type Bill)
 */
List customerGetBillList(Customer customer);

/**
 * get a list of rented cars for a customer
 * @param customer - the customer to check
 * return:
 * 	NULL if customer is NULL or memory allocation failed.
 * 	a list of the customer's rented cars (of type Car)
 */
List customerGetRentedCarsList(Customer customer);

/**
 *@param customer - the customer to check
 * return:
 *	the number of cars rented by the customer at the moment
 */
int customerGetNumberOfRentedCars(Customer customer);

/**
 *@param customer - the customer to check
 * return:
 *	the number of cars appearing in the unpayed bill
 */
int customerGetNumberOfCarsInBill(Customer customer);

/**
 * customerPayBill: zeros all the fees for the customer and update the
 * amount payed until now by the customer.
 * @param customer - the paying customer
 * return:
 * 	CUSTOMER_NULL_ARGUMENT - if customer is NULL
 * 	CUSTOMER_SUCCESS - otherwise
 */
CustomerResult customerPayBill(Customer customer);

#endif /* CUSTOMER_H_ */
